﻿using System;
using System.Collections;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections.Generic;

namespace GT
{
    public static partial class Functions
    {
        public static void RunInThread(object arg, Action<object> action)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(
                (Action<object>)delegate(object argument)
                {
                    try
                    {
                        action(argument);
                    }
                    catch { throw; }
                }
                ), arg);
        }

        public static void RunInThread<T>(T arg, Action<T> action)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(
                (Action<object>)delegate(object argument)
                {
                    try
                    {
                        action((T)argument);
                    }
                    catch { throw; }
                }
                ), arg);
        }
    }

    public class Comparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T, T, bool> _lambdaComparer;
        private readonly Func<T, int> _lambdaHash;

        public Comparer(Func<T, T, bool> comparer) :
            this(comparer, o => 0)
        {
        }

        public Comparer(Func<T, T, bool> comparer, Func<T, int> hash)
        {
            if (comparer == null)
                throw new ArgumentNullException("comparer");
            if (hash == null)
                throw new ArgumentNullException("hash");

            _lambdaComparer = comparer;
            _lambdaHash = hash;
        }

        public bool Equals(T x, T y)
        {
            return _lambdaComparer(x, y);
        }

        public int GetHashCode(T obj)
        {
            return _lambdaHash(obj);
        }
    }

    public static partial class Extensions
    {
        [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
        private static extern int FindMimeFromData(IntPtr pBC,
            [MarshalAs(UnmanagedType.LPWStr)]
            string pwzUrl,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)]
            byte[] pBuffer,
            int cbSize,
            [MarshalAs(UnmanagedType.LPWStr)]
            string pwzMimeProposed,
            int dwMimeFlags,
            out IntPtr ppwzMimeOut,
            int dwReserved);


        
        #region Helper methods

        private static Object[] GetRowFields(DataRow dr, String[] arrFieldNames)
        {
            if (arrFieldNames.Length == 1)
                return new Object[] { dr[arrFieldNames[0]] };
            else
            {
                ArrayList itemArray = new ArrayList();
                foreach (String field in arrFieldNames)
                    itemArray.Add(dr[field]);

                return itemArray.ToArray();
            }
        }

        private static Boolean ObjectComparison(Object a, Object b)
        {
            if (a == DBNull.Value && b == DBNull.Value) //  both are DBNull.Value
                return true;
            if (a == DBNull.Value || b == DBNull.Value) //  only one is DBNull.Value
                return false;
            return (a.Equals(b));  // value type standard comparison
        }

        private static Boolean ObjectComparison(Object[] a, Object[] b)
        {
            Boolean retValue = true;
            Boolean singleCheck = false;

            if (a.Length == b.Length)
                for (Int32 i = 0; i < a.Length; i++)
                {
                    if (!(singleCheck = ObjectComparison(a[i], b[i])))
                    {
                        retValue = false;
                        break;
                    }
                    retValue = retValue && singleCheck;
                }

            return retValue;
        }

        #endregion
    }
}
